package climspace.ejb;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import climspace.data.WeatherData;
import climspace.data.WeatherStation;
import climspace.hadoop.ArchiveStation;
import climspace.hadoop.ArchiveStationImpl;

@Remote(WeatherStationBean.class)
@Stateless
public class WeatherStationBeanEJB implements WeatherStationBean{

	private static final long serialVersionUID = -7129247785747119428L;

	@Resource
	private SessionContext ctx;

	@PersistenceContext(unitName = "persistenceRDBMS")
	private EntityManager data;

	@Override
	public String getCurrentWeatherData(String stationId, String desiredOutputFormat) {
		//Query q = data.createNamedQuery("findWeatherData");
		//q.setParameter("primary_id", primary_id);
		//WeatherStation weatherStation = data.find(WeatherStation.class, "KIYA");
		//Query q = data.createNativeQuery("select ws.latitude, ws.longitude, wd.* from WeatherStation ws,WeatherData wd where ws.primary_id = '"+ primary_id+ "' and ws.primary_id=wd.primary_id");
		
		Long start = System.currentTimeMillis();
		Long begin = start;

		Query queryWeatherStation = data.createNamedQuery("findWeatherStation");
		queryWeatherStation.setParameter("primary_id", stationId);
	
		Query queryWeatherData = data.createNamedQuery("getWeatherDataByStationID");
		queryWeatherData.setParameter("primary_id", stationId);
		
		//Query q = data.createNamedQuery("findWeatherData");
		//q.setParameter("primary_id", primary_id);
		
		
		List<WeatherData> weatherDataList = (List<WeatherData> ) queryWeatherData.getResultList();
		List<WeatherStation> weatherStation = (List<WeatherStation> ) queryWeatherStation.getResultList();
		
		WeatherDataOutput weatherDataOutput = null;
		if (weatherDataList.size()>=1 && weatherStation.size() >=1)
			weatherDataOutput = new WeatherDataOutput(weatherStation.get(0), weatherDataList.get(0));
		//WeatherStation weatherStation = (WeatherStation) q.getSingleResult();
		
		Long end = System.currentTimeMillis();
		System.out.println("**PERF** Query time (ms): " + (end-start));
		start = end;
		
		String outputString = "";
		OutputFormatInterface outputFormat;
		if(Constants.JSON_OUTPUT_FORMAT.equals(desiredOutputFormat)){
			outputFormat = new JsonOutputFormat();
		} else if(Constants.KML_OUTPUT_FORMAT.equals(desiredOutputFormat)){
			outputFormat = new KmlOutputFormat();
		} else {
			System.out.println(desiredOutputFormat + " Output Format is not Supported!");
			return null;
		}
		outputString = outputFormat.objectToText(weatherDataOutput);
		
		end = System.currentTimeMillis();
		System.out.println("**PERF** KML/JSON gen time (ms): " + (end-start));
		System.out.println("**PERF** Total GetCurrentWeatherData (ms): " + (end-begin));
		
		return  outputString;
	}

	@Override
	public String getHistoricalWeatherData(String stationId, Date fromDate,
			Date toDate, String userName) {
		String jobID = null;
		try {
			SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
			String fromDateString = formatter.format(fromDate);
			String toDateString = formatter.format(toDate);
			SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
			jobID = userName + dateFormatter.format(new Date());
			sendMessage(stationId, fromDateString, toDateString, jobID);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return jobID;
	}	
	private void sendMessage(String stationId, String fromDate, String toDate, String jobID) {
		QueueSession session = null;
		QueueSender sender = null;
		QueueConnection cnn = null;
		try {
			Queue queue = (Queue) ctx.lookup("/queue/climspace/hdfs");

			QueueConnectionFactory factory = (QueueConnectionFactory) ctx
					.lookup("ConnectionFactory");
			cnn = factory.createQueueConnection();
			session = cnn.createQueueSession(false,
					QueueSession.AUTO_ACKNOWLEDGE);
			sender = session.createSender(queue);

			MapMessage m = session.createMapMessage();
			m.setString("stationId",stationId);
			m.setString("fromDate", fromDate);
			m.setString("toDate", toDate);
			m.setString("jobID", jobID);

			sender.send(m);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				sender.close();
				session.close();
				cnn.close();
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public String downloadDataFileByJobID(String jobID, String outFolder) {
		String outFile = "";
		// TODO ArchiveStation with default configurations
		ArchiveStation archiveStation = new ArchiveStationImpl();
		outFile = archiveStation.downloadDataFileByJobID(jobID, outFolder);
		return outFile;
	}
}
